summaryrefslogtreecommitdiff
path: root/gcc/cp/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r--gcc/cp/call.c431
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);