diff options
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r-- | gcc/cp/call.c | 431 |
1 files changed, 259 insertions, 172 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 41e6933f686..29dda07426f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -126,21 +126,21 @@ static struct z_candidate * tourney (struct z_candidate *); static int equal_functions (tree, tree); static int joust (struct z_candidate *, struct z_candidate *, bool); static int compare_ics (conversion *, conversion *); -static tree build_over_call (struct z_candidate *, int); +static tree build_over_call (struct z_candidate *, int, tsubst_flags_t); static tree build_java_interface_fn_ref (tree, tree); -#define convert_like(CONV, EXPR) \ +#define convert_like(CONV, EXPR, COMPLAIN) \ convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0, \ /*issue_conversion_warnings=*/true, \ - /*c_cast_p=*/false) -#define convert_like_with_context(CONV, EXPR, FN, ARGNO) \ - convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0, \ - /*issue_conversion_warnings=*/true, \ - /*c_cast_p=*/false) + /*c_cast_p=*/false, (COMPLAIN)) +#define convert_like_with_context(CONV, EXPR, FN, ARGNO, COMPLAIN ) \ + convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0, \ + /*issue_conversion_warnings=*/true, \ + /*c_cast_p=*/false, (COMPLAIN)) static tree convert_like_real (conversion *, tree, tree, int, int, bool, - bool); + bool, tsubst_flags_t); static void op_error (enum tree_code, enum tree_code, tree, tree, tree, const char *); -static tree build_object_call (tree, tree); +static tree build_object_call (tree, tree, tsubst_flags_t); static tree resolve_args (tree); static struct z_candidate *build_user_type_conversion_1 (tree, tree, int); static void print_z_candidate (const char *, struct z_candidate *); @@ -2418,7 +2418,7 @@ build_this (tree obj) if (processing_template_decl) return build_address (obj); - return build_unary_op (ADDR_EXPR, obj, 0); + return cp_build_unary_op (ADDR_EXPR, obj, 0, tf_warning_or_error); } /* Returns true iff functions are equivalent. Equivalent functions are @@ -2750,7 +2750,7 @@ build_user_type_conversion (tree totype, tree expr, int flags) { if (cand->second_conv->kind == ck_ambig) return error_mark_node; - expr = convert_like (cand->second_conv, expr); + expr = convert_like (cand->second_conv, expr, tf_warning_or_error); return convert_from_reference (expr); } return NULL_TREE; @@ -2773,7 +2773,7 @@ resolve_args (tree args) error ("invalid use of void expression"); return error_mark_node; } - else if (invalid_nonstatic_memfn_p (arg)) + else if (invalid_nonstatic_memfn_p (arg, tf_warning_or_error)) return error_mark_node; } return args; @@ -2837,7 +2837,8 @@ perform_overload_resolution (tree fn, or a static member function) with the ARGS. */ tree -build_new_function_call (tree fn, tree args, bool koenig_p) +build_new_function_call (tree fn, tree args, bool koenig_p, + tsubst_flags_t complain) { struct z_candidate *candidates, *cand; bool any_viable_p; @@ -2858,8 +2859,9 @@ build_new_function_call (tree fn, tree args, bool koenig_p) fn = remove_hidden_names (fn); if (!fn) { - error ("no matching function for call to %<%D(%A)%>", - DECL_NAME (OVL_CURRENT (orig_fn)), args); + if (complain & tf_error) + error ("no matching function for call to %<%D(%A)%>", + DECL_NAME (OVL_CURRENT (orig_fn)), args); return error_mark_node; } } @@ -2871,22 +2873,25 @@ build_new_function_call (tree fn, tree args, bool koenig_p) if (!cand) { - if (!any_viable_p && candidates && ! candidates->next) - return build_function_call (candidates->fn, args); - if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) - fn = TREE_OPERAND (fn, 0); - if (!any_viable_p) - error ("no matching function for call to %<%D(%A)%>", - DECL_NAME (OVL_CURRENT (fn)), args); - else - error ("call of overloaded %<%D(%A)%> is ambiguous", - DECL_NAME (OVL_CURRENT (fn)), args); - if (candidates) - print_z_candidates (candidates); + if (complain & tf_error) + { + if (!any_viable_p && candidates && ! candidates->next) + return cp_build_function_call (candidates->fn, args, complain); + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) + fn = TREE_OPERAND (fn, 0); + if (!any_viable_p) + error ("no matching function for call to %<%D(%A)%>", + DECL_NAME (OVL_CURRENT (fn)), args); + else + error ("call of overloaded %<%D(%A)%> is ambiguous", + DECL_NAME (OVL_CURRENT (fn)), args); + if (candidates) + print_z_candidates (candidates); + } result = error_mark_node; } else - result = build_over_call (cand, LOOKUP_NORMAL); + result = build_over_call (cand, LOOKUP_NORMAL, complain); /* Free all the conversions we allocated. */ obstack_free (&conversion_obstack, p); @@ -2997,11 +3002,11 @@ build_operator_new_call (tree fnname, tree args, *fn = cand->fn; /* Build the CALL_EXPR. */ - return build_over_call (cand, LOOKUP_NORMAL); + return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error); } static tree -build_object_call (tree obj, tree args) +build_object_call (tree obj, tree args, tsubst_flags_t complain) { struct z_candidate *candidates = 0, *cand; tree fns, convs, mem_args = NULL_TREE; @@ -3012,9 +3017,10 @@ build_object_call (tree obj, tree args) if (TYPE_PTRMEMFUNC_P (type)) { - /* It's no good looking for an overloaded operator() on a - pointer-to-member-function. */ - error ("pointer-to-member function %E cannot be called without an object; consider using .* or ->*", obj); + if (complain & tf_error) + /* It's no good looking for an overloaded operator() on a + pointer-to-member-function. */ + error ("pointer-to-member function %E cannot be called without an object; consider using .* or ->*", obj); return error_mark_node; } @@ -3088,8 +3094,11 @@ build_object_call (tree obj, tree args) candidates = splice_viable (candidates, pedantic, &any_viable_p); if (!any_viable_p) { - error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj), args); - print_z_candidates (candidates); + if (complain & tf_error) + { + error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj), args); + print_z_candidates (candidates); + } result = error_mark_node; } else @@ -3097,8 +3106,12 @@ build_object_call (tree obj, tree args) cand = tourney (candidates); if (cand == 0) { - error ("call of %<(%T) (%A)%> is ambiguous", TREE_TYPE (obj), args); - print_z_candidates (candidates); + if (complain & tf_error) + { + error ("call of %<(%T) (%A)%> is ambiguous", + TREE_TYPE (obj), args); + print_z_candidates (candidates); + } result = error_mark_node; } /* Since cand->fn will be a type, not a function, for a conversion @@ -3106,12 +3119,13 @@ build_object_call (tree obj, tree args) DECL_NAME here. */ else if (TREE_CODE (cand->fn) == FUNCTION_DECL && DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR) - result = build_over_call (cand, LOOKUP_NORMAL); + result = build_over_call (cand, LOOKUP_NORMAL, complain); else { - obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1); + obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1, + complain); obj = convert_from_reference (obj); - result = build_function_call (obj, args); + result = cp_build_function_call (obj, args, complain); } } @@ -3232,7 +3246,8 @@ conditional_conversion (tree e1, tree e2) arguments to the conditional expression. */ tree -build_conditional_expr (tree arg1, tree arg2, tree arg3) +build_conditional_expr (tree arg1, tree arg2, tree arg3, + tsubst_flags_t complain) { tree arg2_type; tree arg3_type; @@ -3249,7 +3264,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) calculated only once. */ if (!arg2) { - if (pedantic) + if (pedantic && (complain & tf_error)) pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression"); /* Make sure that lvalues remain lvalues. See g++.oliva/ext1.C. */ @@ -3263,7 +3278,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) The first expr ession is implicitly converted to bool (clause _conv_). */ - arg1 = perform_implicit_conversion (boolean_type_node, arg1); + arg1 = perform_implicit_conversion (boolean_type_node, arg1, complain); /* If something has already gone wrong, just pass that fact up the tree. */ @@ -3327,16 +3342,19 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) result_type = void_type_node; else { - if (VOID_TYPE_P (arg2_type)) - error ("second operand to the conditional operator " - "is of type %<void%>, " - "but the third operand is neither a throw-expression " - "nor of type %<void%>"); - else - error ("third operand to the conditional operator " - "is of type %<void%>, " - "but the second operand is neither a throw-expression " - "nor of type %<void%>"); + if (complain & tf_error) + { + if (VOID_TYPE_P (arg2_type)) + error ("second operand to the conditional operator " + "is of type %<void%>, " + "but the third operand is neither a throw-expression " + "nor of type %<void%>"); + else + error ("third operand to the conditional operator " + "is of type %<void%>, " + "but the second operand is neither a throw-expression " + "nor of type %<void%>"); + } return error_mark_node; } @@ -3380,7 +3398,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) } else if (conv2 && (!conv2->bad_p || !conv3)) { - arg2 = convert_like (conv2, arg2); + arg2 = convert_like (conv2, arg2, complain); arg2 = convert_from_reference (arg2); arg2_type = TREE_TYPE (arg2); /* Even if CONV2 is a valid conversion, the result of the @@ -3393,7 +3411,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) } else if (conv3 && (!conv3->bad_p || !conv2)) { - arg3 = convert_like (conv3, arg3); + arg3 = convert_like (conv3, arg3, complain); arg3 = convert_from_reference (arg3); arg3_type = TREE_TYPE (arg3); if (error_operand_p (arg3)) @@ -3477,15 +3495,21 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) candidates = splice_viable (candidates, pedantic, &any_viable_p); if (!any_viable_p) { - op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match"); - print_z_candidates (candidates); + if (complain & tf_error) + { + op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match"); + print_z_candidates (candidates); + } return error_mark_node; } cand = tourney (candidates); if (!cand) { - op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match"); - print_z_candidates (candidates); + if (complain & tf_error) + { + op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match"); + print_z_candidates (candidates); + } return error_mark_node; } @@ -3495,11 +3519,11 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) the converted operands are used in place of the original operands for the remainder of this section. */ conv = cand->convs[0]; - arg1 = convert_like (conv, arg1); + arg1 = convert_like (conv, arg1, complain); conv = cand->convs[1]; - arg2 = convert_like (conv, arg2); + arg2 = convert_like (conv, arg2, complain); conv = cand->convs[2]; - arg3 = convert_like (conv, arg3); + arg3 = convert_like (conv, arg3, complain); } /* [expr.cond] @@ -3548,17 +3572,25 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) if (TREE_CODE (arg2_type) == ENUMERAL_TYPE && TREE_CODE (arg3_type) == ENUMERAL_TYPE) - warning (0, "enumeral mismatch in conditional expression: %qT vs %qT", - arg2_type, arg3_type); + { + if (complain & tf_warning) + warning (0, + "enumeral mismatch in conditional expression: %qT vs %qT", + arg2_type, arg3_type); + } else if (extra_warnings && ((TREE_CODE (arg2_type) == ENUMERAL_TYPE && !same_type_p (arg3_type, type_promotes_to (arg2_type))) || (TREE_CODE (arg3_type) == ENUMERAL_TYPE && !same_type_p (arg2_type, type_promotes_to (arg3_type))))) - warning (0, "enumeral and non-enumeral type in conditional expression"); + { + if (complain & tf_warning) + warning (0, + "enumeral and non-enumeral type in conditional expression"); + } - arg2 = perform_implicit_conversion (result_type, arg2); - arg3 = perform_implicit_conversion (result_type, arg3); + arg2 = perform_implicit_conversion (result_type, arg2, complain); + arg3 = perform_implicit_conversion (result_type, arg3, complain); } /* [expr.cond] @@ -3585,17 +3617,19 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type))) { result_type = composite_pointer_type (arg2_type, arg3_type, arg2, - arg3, "conditional expression"); + arg3, "conditional expression", + complain); if (result_type == error_mark_node) return error_mark_node; - arg2 = perform_implicit_conversion (result_type, arg2); - arg3 = perform_implicit_conversion (result_type, arg3); + arg2 = perform_implicit_conversion (result_type, arg2, complain); + arg3 = perform_implicit_conversion (result_type, arg3, complain); } if (!result_type) { - error ("operands to ?: have different types %qT and %qT", - arg2_type, arg3_type); + if (complain & tf_error) + error ("operands to ?: have different types %qT and %qT", + arg2_type, arg3_type); return error_mark_node; } @@ -3707,7 +3741,7 @@ add_candidates (tree fns, tree args, tree build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, - bool *overloaded_p) + bool *overloaded_p, tsubst_flags_t complain) { struct z_candidate *candidates = 0, *cand; tree arglist, fnname; @@ -3747,7 +3781,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, gcc_unreachable (); case CALL_EXPR: - return build_object_call (arg1, arg2); + return build_object_call (arg1, arg2, complain); case TRUTH_ORIF_EXPR: case TRUTH_ANDIF_EXPR: @@ -3856,6 +3890,11 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, { case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: + /* Don't try anything fancy if we're not allowed to produce + errors. */ + if (!(complain & tf_error)) + return error_mark_node; + /* Look for an `operator++ (int)'. If they didn't have one, then we fall back to the old way of doing things. */ if (flags & LOOKUP_COMPLAIN) @@ -3868,7 +3907,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, else code = PREDECREMENT_EXPR; result = build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE, - overloaded_p); + overloaded_p, complain); break; /* The caller will deal with these. */ @@ -3880,7 +3919,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, break; default: - if (flags & LOOKUP_COMPLAIN) + if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error)) { op_error (code, code2, arg1, arg2, arg3, "no match"); print_z_candidates (candidates); @@ -3894,7 +3933,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, cand = tourney (candidates); if (cand == 0) { - if (flags & LOOKUP_COMPLAIN) + if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error)) { op_error (code, code2, arg1, arg2, arg3, "ambiguous overload"); print_z_candidates (candidates); @@ -3909,12 +3948,12 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, if (resolve_args (arglist) == error_mark_node) result = error_mark_node; else - result = build_over_call (cand, LOOKUP_NORMAL); + result = build_over_call (cand, LOOKUP_NORMAL, complain); } else { /* 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) @@ -3933,7 +3972,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE && TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) - != TYPE_MAIN_VARIANT (TREE_TYPE (arg2)))) + != TYPE_MAIN_VARIANT (TREE_TYPE (arg2))) + && (complain & tf_warning)) { warning (0, "comparison between %q#T and %q#T", TREE_TYPE (arg1), TREE_TYPE (arg2)); @@ -3950,25 +3990,26 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, conv = cand->convs[0]; if (conv->kind == ck_ref_bind) conv = conv->u.next; - arg1 = convert_like (conv, arg1); + arg1 = convert_like (conv, arg1, complain); if (arg2) { conv = cand->convs[1]; if (conv->kind == ck_ref_bind) conv = conv->u.next; - arg2 = convert_like (conv, arg2); + arg2 = convert_like (conv, arg2, complain); } if (arg3) { conv = cand->convs[2]; if (conv->kind == ck_ref_bind) conv = conv->u.next; - arg3 = convert_like (conv, arg3); + arg3 = convert_like (conv, arg3, complain); } if (!expl_eq_arg1) { - warn_logical_operator (code, arg1, arg2); + if (complain & tf_warning) + warn_logical_operator (code, arg1, arg2); expl_eq_arg1 = true; } } @@ -3986,10 +4027,10 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, switch (code) { case MODIFY_EXPR: - return build_modify_expr (arg1, code2, arg2); + return cp_build_modify_expr (arg1, code2, arg2, complain); case INDIRECT_REF: - return build_indirect_ref (arg1, "unary *"); + return cp_build_indirect_ref (arg1, "unary *", complain); case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: @@ -4015,7 +4056,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: - return cp_build_binary_op (code, arg1, arg2); + return cp_build_binary_op (code, arg1, arg2, complain); case UNARY_PLUS_EXPR: case NEGATE_EXPR: @@ -4027,16 +4068,18 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, case POSTDECREMENT_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: - return build_unary_op (code, arg1, candidates != 0); + return cp_build_unary_op (code, arg1, candidates != 0, complain); case ARRAY_REF: return build_array_ref (arg1, arg2); case COND_EXPR: - return build_conditional_expr (arg1, arg2, arg3); + return build_conditional_expr (arg1, arg2, arg3, complain); case MEMBER_REF: - return build_m_component_ref (build_indirect_ref (arg1, NULL), arg2); + return build_m_component_ref (cp_build_indirect_ref (arg1, NULL, + complain), + arg2); /* The caller will deal with these. */ case ADDR_EXPR: @@ -4205,7 +4248,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, else args = tree_cons (NULL_TREE, addr, build_tree_list (NULL_TREE, size)); - return build_function_call (fn, args); + return cp_build_function_call (fn, args, tf_warning_or_error); } } @@ -4268,7 +4311,7 @@ build_temp (tree expr, tree type, int flags, expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, expr), - type, flags); + type, flags, tf_warning_or_error); if (warningcount > savew) *diagnostic_fn = warning0; else if (errorcount > savee) @@ -4317,7 +4360,7 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum) static tree convert_like_real (conversion *convs, tree expr, tree fn, int argnum, int inner, bool issue_conversion_warnings, - bool c_cast_p) + bool c_cast_p, tsubst_flags_t complain) { tree totype = convs->type; diagnostic_fn_t diagnostic_fn; @@ -4335,23 +4378,31 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, { expr = convert_like_real (t, expr, fn, argnum, 1, /*issue_conversion_warnings=*/false, - /*c_cast_p=*/false); + /*c_cast_p=*/false, + complain); break; } else if (t->kind == ck_ambig) return convert_like_real (t, expr, fn, argnum, 1, /*issue_conversion_warnings=*/false, - /*c_cast_p=*/false); + /*c_cast_p=*/false, + complain); else if (t->kind == ck_identity) break; } - permerror ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype); - if (fn) - permerror (" initializing argument %P of %qD", argnum, fn); + if (complain & tf_error) + { + permerror ("invalid conversion from %qT to %qT", TREE_TYPE (expr), totype); + if (fn) + permerror (" initializing argument %P of %qD", argnum, fn); + } + else + return error_mark_node; + return cp_convert (totype, expr); } - if (issue_conversion_warnings) + if (issue_conversion_warnings && (complain & tf_warning)) conversion_null_warnings (totype, expr, fn, argnum); switch (convs->kind) @@ -4367,7 +4418,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, for (i = 0; i < cand->num_convs; ++i) cand->convs[i]->user_conv_p = true; - expr = build_over_call (cand, LOOKUP_NORMAL); + expr = build_over_call (cand, LOOKUP_NORMAL, complain); /* If this is a constructor or a function returning an aggr type, we need to build up a TARGET_EXPR. */ @@ -4394,7 +4445,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION, &diagnostic_fn)); - if (diagnostic_fn) + if (diagnostic_fn && (complain & tf_error)) { if (fn) diagnostic_fn @@ -4410,7 +4461,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, } case ck_identity: if (type_unknown_p (expr)) - expr = instantiate_type (totype, expr, tf_warning_or_error); + expr = instantiate_type (totype, expr, complain); /* Convert a constant to its underlying value, unless we are about to bind it to a reference, in which case we need to leave it as an lvalue. */ @@ -4436,7 +4487,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, expr = convert_like_real (convs->u.next, expr, fn, argnum, convs->kind == ck_ref_bind ? -1 : 1, convs->kind == ck_ref_bind ? issue_conversion_warnings : false, - c_cast_p); + c_cast_p, + complain); if (expr == error_mark_node) return error_mark_node; @@ -4453,10 +4505,10 @@ 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 = build_unary_op (ADDR_EXPR, expr, 0); + expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain); expr = convert_to_base (expr, build_pointer_type (totype), !c_cast_p, /*nonnull=*/true); - expr = build_indirect_ref (expr, "implicit conversion"); + expr = cp_build_indirect_ref (expr, "implicit conversion", complain); return expr; } @@ -4470,7 +4522,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, flags |= LOOKUP_NO_CONVERSION; expr = build_temp (expr, totype, flags, &diagnostic_fn); if (diagnostic_fn && fn) - diagnostic_fn (" initializing argument %P of %qD", argnum, fn); + { + if ((complain & tf_error)) + diagnostic_fn (" initializing argument %P of %qD", argnum, fn); + else if (diagnostic_fn == error) + return error_mark_node; + } return build_cplus_new (totype, expr); case ck_ref_bind: @@ -4482,7 +4539,7 @@ 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 build_unary_op (ADDR_EXPR, expr, ...) + upcoming call to cp_build_unary_op (ADDR_EXPR, expr, ...) doesn't fail. */ if (convs->need_temporary_p || TREE_CODE (expr) == CONSTRUCTOR @@ -4494,16 +4551,19 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)) && !TYPE_REF_IS_RVALUE (ref_type)) { - /* If the reference is volatile or non-const, we - cannot create a temporary. */ - if (lvalue & clk_bitfield) - error ("cannot bind bitfield %qE to %qT", - expr, ref_type); - else if (lvalue & clk_packed) - error ("cannot bind packed field %qE to %qT", - expr, ref_type); - else - error ("cannot bind rvalue %qE to %qT", expr, ref_type); + if (complain & tf_error) + { + /* If the reference is volatile or non-const, we + cannot create a temporary. */ + if (lvalue & clk_bitfield) + error ("cannot bind bitfield %qE to %qT", + expr, ref_type); + else if (lvalue & clk_packed) + error ("cannot bind packed field %qE to %qT", + expr, ref_type); + else + error ("cannot bind rvalue %qE to %qT", expr, ref_type); + } return error_mark_node; } /* If the source is a packed field, and we must use a copy @@ -4516,8 +4576,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, && CLASS_TYPE_P (type) && !TYPE_HAS_TRIVIAL_INIT_REF (type)) { - error ("cannot bind packed field %qE to %qT", - expr, ref_type); + if (complain & tf_error) + error ("cannot bind packed field %qE to %qT", + expr, ref_type); return error_mark_node; } if (lvalue & clk_bitfield) @@ -4527,7 +4588,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 = build_unary_op (ADDR_EXPR, expr, 1); + expr = cp_build_unary_op (ADDR_EXPR, expr, 1, complain); if (expr == error_mark_node) return error_mark_node; @@ -4652,7 +4713,7 @@ build_x_va_arg (tree expr, tree type) expr = convert (build_pointer_type (type1), null_node); expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), call_builtin_trap (), expr); - expr = build_indirect_ref (expr, NULL); + expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error); return expr; } @@ -4719,7 +4780,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) { arg = digest_init (type, arg); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", fn, parmnum); + "default argument", fn, parmnum, + tf_warning_or_error); } else { @@ -4732,7 +4794,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) if (!CONSTANT_CLASS_P (arg)) arg = unshare_expr (arg); arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", fn, parmnum); + "default argument", fn, parmnum, + tf_warning_or_error); arg = convert_for_arg_passing (type, arg); } @@ -4845,7 +4908,7 @@ magic_varargs_p (tree fn) bitmask of various LOOKUP_* flags which apply to the call itself. */ static tree -build_over_call (struct z_candidate *cand, int flags) +build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) { tree fn = cand->fn; tree args = cand->args; @@ -4957,8 +5020,13 @@ build_over_call (struct z_candidate *cand, int flags) tree base_binfo; if (convs[i]->bad_p) - permerror ("passing %qT as %<this%> argument of %q#D discards qualifiers", - TREE_TYPE (argtype), fn); + { + if (complain & tf_error) + permerror ("passing %qT as %<this%> argument of %q#D discards qualifiers", + TREE_TYPE (argtype), fn); + else + return error_mark_node; + } /* [class.mfct.nonstatic]: If a nonstatic member function of a class X is called for an object that is not of type X, or of a type @@ -5008,10 +5076,13 @@ build_over_call (struct z_candidate *cand, int flags) conv = conv->u.next; val = convert_like_with_context - (conv, TREE_VALUE (arg), fn, i - is_method); + (conv, TREE_VALUE (arg), fn, i - is_method, complain); val = convert_for_arg_passing (type, val); - argarray[j++] = val; + if ((complain == tf_none) && val == error_mark_node) + return error_mark_node; + else + argarray[j++] = val; } /* Default arguments */ @@ -5067,7 +5138,7 @@ build_over_call (struct z_candidate *cand, int flags) if (targ) arg = targ; else - arg = build_indirect_ref (arg, 0); + arg = cp_build_indirect_ref (arg, 0, complain); /* [class.copy]: the copy constructor is implicitly defined even if the implementation elided its use. */ @@ -5091,7 +5162,7 @@ build_over_call (struct z_candidate *cand, int flags) && !move_fn_p (fn))) { tree to = stabilize_reference - (build_indirect_ref (TREE_VALUE (args), 0)); + (cp_build_indirect_ref (TREE_VALUE (args), 0, complain)); val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg); return val; @@ -5102,14 +5173,14 @@ build_over_call (struct z_candidate *cand, int flags) && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn))) { tree to = stabilize_reference - (build_indirect_ref (argarray[0], 0)); + (cp_build_indirect_ref (argarray[0], 0, complain)); tree type = TREE_TYPE (to); tree as_base = CLASSTYPE_AS_BASE (type); arg = argarray[1]; if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base))) { - arg = build_indirect_ref (arg, 0); + arg = cp_build_indirect_ref (arg, 0, complain); val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg); } else @@ -5121,12 +5192,12 @@ build_over_call (struct z_candidate *cand, int flags) arg2 = TYPE_SIZE_UNIT (as_base); arg1 = arg; - arg0 = build_unary_op (ADDR_EXPR, to, 0); + arg0 = cp_build_unary_op (ADDR_EXPR, to, 0, complain); t = implicit_built_in_decls[BUILT_IN_MEMCPY]; t = build_call_n (t, 3, arg0, arg1, arg2); t = convert (TREE_TYPE (arg0), t); - val = build_indirect_ref (t, 0); + val = cp_build_indirect_ref (t, 0, complain); } return val; @@ -5227,7 +5298,8 @@ build_java_interface_fn_ref (tree fn, tree instance) /* Look up the pointer to the runtime java.lang.Class object for `instance'. This is the first entry in the vtable. */ - klass_ref = build_vtbl_ref (build_indirect_ref (instance, 0), + klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, 0, + tf_warning_or_error), integer_zero_node); /* Get the java.lang.Class pointer for the interface being called. */ @@ -5300,7 +5372,7 @@ in_charge_arg_for_name (tree name) tree build_special_member_call (tree instance, tree name, tree args, - tree binfo, int flags) + tree binfo, int flags, tsubst_flags_t complain) { tree fns; /* The type of the subobject to be constructed or destroyed. */ @@ -5390,7 +5462,8 @@ build_special_member_call (tree instance, tree name, tree args, return build_new_method_call (instance, fns, args, TYPE_BINFO (BINFO_TYPE (binfo)), - flags, /*fn=*/NULL); + flags, /*fn=*/NULL, + complain); } /* Return the NAME, as a C string. The NAME indicates a function that @@ -5444,7 +5517,7 @@ name_as_c_string (tree name, tree type, bool *free_p) tree build_new_method_call (tree instance, tree fns, tree args, tree conversion_path, int flags, - tree *fn_p) + tree *fn_p, tsubst_flags_t complain) { struct z_candidate *candidates = 0, *cand; tree explicit_targs = NULL_TREE; @@ -5477,7 +5550,8 @@ build_new_method_call (tree instance, tree fns, tree args, if (!BASELINK_P (fns)) { - error ("call to non-function %qD", fns); + if (complain & tf_error) + error ("call to non-function %qD", fns); return error_mark_node; } @@ -5594,21 +5668,24 @@ build_new_method_call (tree instance, tree fns, tree args, candidates = splice_viable (candidates, pedantic, &any_viable_p); if (!any_viable_p) { - if (!COMPLETE_TYPE_P (basetype)) - cxx_incomplete_type_error (instance_ptr, basetype); - else + if (complain & tf_error) { - char *pretty_name; - bool free_p; - - pretty_name = name_as_c_string (name, basetype, &free_p); - error ("no matching function for call to %<%T::%s(%A)%#V%>", - basetype, pretty_name, user_args, - TREE_TYPE (TREE_TYPE (instance_ptr))); - if (free_p) - free (pretty_name); + if (!COMPLETE_TYPE_P (basetype)) + cxx_incomplete_type_error (instance_ptr, basetype); + else + { + char *pretty_name; + bool free_p; + + pretty_name = name_as_c_string (name, basetype, &free_p); + error ("no matching function for call to %<%T::%s(%A)%#V%>", + basetype, pretty_name, user_args, + TREE_TYPE (TREE_TYPE (instance_ptr))); + if (free_p) + free (pretty_name); + } + print_z_candidates (candidates); } - print_z_candidates (candidates); call = error_mark_node; } else @@ -5619,12 +5696,15 @@ build_new_method_call (tree instance, tree fns, tree args, char *pretty_name; bool free_p; - pretty_name = name_as_c_string (name, basetype, &free_p); - error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name, - user_args); - print_z_candidates (candidates); - if (free_p) - free (pretty_name); + if (complain & tf_error) + { + pretty_name = name_as_c_string (name, basetype, &free_p); + error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name, + user_args); + print_z_candidates (candidates); + if (free_p) + free (pretty_name); + } call = error_mark_node; } else @@ -5635,7 +5715,8 @@ build_new_method_call (tree instance, tree fns, tree args, && DECL_PURE_VIRTUAL_P (fn) && instance == current_class_ref && (DECL_CONSTRUCTOR_P (current_function_decl) - || DECL_DESTRUCTOR_P (current_function_decl))) + || DECL_DESTRUCTOR_P (current_function_decl)) + && (complain & tf_warning)) /* This is not an error, it is runtime undefined behavior. */ warning (0, (DECL_CONSTRUCTOR_P (current_function_decl) ? @@ -5646,8 +5727,9 @@ build_new_method_call (tree instance, tree fns, tree args, if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE && is_dummy_object (instance_ptr)) { - error ("cannot call member function %qD without object", - fn); + if (complain & tf_error) + error ("cannot call member function %qD without object", + fn); call = error_mark_node; } else @@ -5659,7 +5741,7 @@ build_new_method_call (tree instance, tree fns, tree args, if (fn_p) *fn_p = fn; /* Build the actual CALL_EXPR. */ - call = build_over_call (cand, flags); + call = build_over_call (cand, flags, complain); /* In an expression of the form `a->f()' where `f' turns out to be a static member function, `a' is none-the-less evaluated. */ @@ -6608,7 +6690,7 @@ can_convert_arg_bad (tree to, tree from, tree arg) doing a bad conversion, convert_like will complain. */ tree -perform_implicit_conversion (tree type, tree expr) +perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain) { conversion *conv; void *p; @@ -6624,7 +6706,8 @@ perform_implicit_conversion (tree type, tree expr) LOOKUP_NORMAL); if (!conv) { - error ("could not convert %qE to %qT", expr, type); + if (complain & tf_error) + error ("could not convert %qE to %qT", expr, type); expr = error_mark_node; } else if (processing_template_decl) @@ -6636,7 +6719,7 @@ perform_implicit_conversion (tree type, tree expr) expr = build_nop (type, expr); } else - expr = convert_like (conv, expr); + expr = convert_like (conv, expr, complain); /* Free all the conversions we allocated. */ obstack_free (&conversion_obstack, p); @@ -6655,7 +6738,8 @@ perform_implicit_conversion (tree type, tree expr) tree perform_direct_initialization_if_possible (tree type, tree expr, - bool c_cast_p) + bool c_cast_p, + tsubst_flags_t complain) { conversion *conv; void *p; @@ -6674,7 +6758,7 @@ perform_direct_initialization_if_possible (tree type, { expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, expr), - type, LOOKUP_NORMAL); + type, LOOKUP_NORMAL, complain); return build_cplus_new (type, expr); } @@ -6689,7 +6773,8 @@ perform_direct_initialization_if_possible (tree type, else expr = convert_like_real (conv, expr, NULL_TREE, 0, 0, /*issue_conversion_warnings=*/false, - c_cast_p); + c_cast_p, + tf_warning_or_error); /* Free all the conversions we allocated. */ obstack_free (&conversion_obstack, p); @@ -6824,7 +6909,8 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) /*fn=*/NULL_TREE, /*argnum=*/0, /*inner=*/-1, /*issue_conversion_warnings=*/true, - /*c_cast_p=*/false); + /*c_cast_p=*/false, + tf_warning_or_error); if (error_operand_p (expr)) expr = error_mark_node; else @@ -6897,17 +6983,18 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) } else /* Take the address of EXPR. */ - expr = build_unary_op (ADDR_EXPR, expr, 0); + expr = cp_build_unary_op (ADDR_EXPR, expr, 0, tf_warning_or_error); /* If a BASE_CONV was required, perform it now. */ if (base_conv_type) expr = (perform_implicit_conversion - (build_pointer_type (base_conv_type), expr)); + (build_pointer_type (base_conv_type), expr, + tf_warning_or_error)); expr = build_nop (type, expr); } } else /* Perform the conversion. */ - expr = convert_like (conv, expr); + expr = convert_like (conv, expr, tf_warning_or_error); /* Free all the conversions we allocated. */ obstack_free (&conversion_obstack, p); |