static bool conversion_obstack_initialized;
struct rejection_reason;
-static struct z_candidate * tourney (struct z_candidate *);
+static struct z_candidate * tourney (struct z_candidate *, tsubst_flags_t);
static int equal_functions (tree, tree);
-static int joust (struct z_candidate *, struct z_candidate *, bool);
+static int joust (struct z_candidate *, struct z_candidate *, bool,
+ tsubst_flags_t);
static int compare_ics (conversion *, conversion *);
static tree build_over_call (struct z_candidate *, int, tsubst_flags_t);
static tree build_java_interface_fn_ref (tree, tree);
bool, tsubst_flags_t);
static void op_error (enum tree_code, enum tree_code, tree, tree,
tree, bool);
-static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
+static struct z_candidate *build_user_type_conversion_1 (tree, tree, int,
+ tsubst_flags_t);
static void print_z_candidate (const char *, struct z_candidate *);
static void print_z_candidates (location_t, struct z_candidate *);
static tree build_this (tree);
static bool any_strictly_viable (struct z_candidate *);
static struct z_candidate *add_template_candidate
(struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
- tree, tree, tree, int, unification_kind_t);
+ tree, tree, tree, int, unification_kind_t, tsubst_flags_t);
static struct z_candidate *add_template_candidate_real
(struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
- tree, tree, tree, int, tree, unification_kind_t);
+ tree, tree, tree, int, tree, unification_kind_t, tsubst_flags_t);
static struct z_candidate *add_template_conv_candidate
(struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
- tree, tree);
+ tree, tree, tsubst_flags_t);
static void add_builtin_candidates
(struct z_candidate **, enum tree_code, enum tree_code,
- tree, tree *, int);
+ tree, tree *, int, tsubst_flags_t);
static void add_builtin_candidate
(struct z_candidate **, enum tree_code, enum tree_code,
- tree, tree, tree, tree *, tree *, int);
+ tree, tree, tree, tree *, tree *, int, tsubst_flags_t);
static bool is_complete (tree);
static void build_builtin_candidate
(struct z_candidate **, tree, tree, tree, tree *, tree *,
- int);
+ int, tsubst_flags_t);
static struct z_candidate *add_conv_candidate
(struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
- tree);
+ tree, tsubst_flags_t);
static struct z_candidate *add_function_candidate
(struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
- tree, int);
-static conversion *implicit_conversion (tree, tree, tree, bool, int);
+ tree, int, tsubst_flags_t);
+static conversion *implicit_conversion (tree, tree, tree, bool, int,
+ tsubst_flags_t);
static conversion *standard_conversion (tree, tree, tree, bool, int);
-static conversion *reference_binding (tree, tree, tree, bool, int);
+static conversion *reference_binding (tree, tree, tree, bool, int,
+ tsubst_flags_t);
static conversion *build_conv (conversion_kind, tree, conversion *);
-static conversion *build_list_conv (tree, tree, int);
+static conversion *build_list_conv (tree, tree, int, tsubst_flags_t);
static conversion *next_conversion (conversion *);
static bool is_subseq (conversion *, conversion *);
static conversion *maybe_handle_ref_bind (conversion **);
static bool reference_compatible_p (tree, tree);
static conversion *direct_reference_binding (tree, conversion *);
static bool promoted_arithmetic_type_p (tree);
-static conversion *conditional_conversion (tree, tree);
+static conversion *conditional_conversion (tree, tree, tsubst_flags_t);
static char *name_as_c_string (tree, tree, bool *);
static tree prep_operand (tree);
static void add_candidates (tree, tree, const VEC(tree,gc) *, tree, tree, bool,
- tree, tree, int, struct z_candidate **);
+ tree, tree, int, struct z_candidate **,
+ tsubst_flags_t);
static conversion *merge_conversion_sequences (conversion *, conversion *);
static bool magic_varargs_p (tree);
static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t);
possible. */
static conversion *
-build_list_conv (tree type, tree ctor, int flags)
+build_list_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
{
tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (type), 0);
unsigned len = CONSTRUCTOR_NELTS (ctor);
{
conversion *sub
= implicit_conversion (elttype, TREE_TYPE (val), val,
- false, flags);
+ false, flags, complain);
if (sub == NULL)
return NULL;
is a valid aggregate initializer for array type ATYPE. */
static bool
-can_convert_array (tree atype, tree ctor, int flags)
+can_convert_array (tree atype, tree ctor, int flags, tsubst_flags_t complain)
{
unsigned i;
tree elttype = TREE_TYPE (atype);
bool ok;
if (TREE_CODE (elttype) == ARRAY_TYPE
&& TREE_CODE (val) == CONSTRUCTOR)
- ok = can_convert_array (elttype, val, flags);
+ ok = can_convert_array (elttype, val, flags, complain);
else
- ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags);
+ ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags,
+ complain);
if (!ok)
return false;
}
aggregate class, if such a conversion is possible. */
static conversion *
-build_aggr_conv (tree type, tree ctor, int flags)
+build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
{
unsigned HOST_WIDE_INT i = 0;
conversion *c;
if (TREE_CODE (ftype) == ARRAY_TYPE
&& TREE_CODE (val) == CONSTRUCTOR)
- ok = can_convert_array (ftype, val, flags);
+ ok = can_convert_array (ftype, val, flags, complain);
else
- ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags);
+ ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags,
+ complain);
if (!ok)
return NULL;
array type, if such a conversion is possible. */
static conversion *
-build_array_conv (tree type, tree ctor, int flags)
+build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
{
conversion *c;
unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor);
{
conversion *sub
= implicit_conversion (elttype, TREE_TYPE (val), val,
- false, flags);
+ false, flags, complain);
if (sub == NULL)
return NULL;
complex type, if such a conversion is possible. */
static conversion *
-build_complex_conv (tree type, tree ctor, int flags)
+build_complex_conv (tree type, tree ctor, int flags,
+ tsubst_flags_t complain)
{
conversion *c;
unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor);
{
conversion *sub
= implicit_conversion (elttype, TREE_TYPE (val), val,
- false, flags);
+ false, flags, complain);
if (sub == NULL)
return NULL;
conversion is coming from a C-style cast. */
static conversion *
-reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
+reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
+ tsubst_flags_t complain)
{
conversion *conv = NULL;
tree to = TREE_TYPE (rto);
{
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
conv = implicit_conversion (to, from, expr, c_cast_p,
- flags);
+ flags, complain);
if (!CLASS_TYPE_P (to)
&& CONSTRUCTOR_NELTS (expr) == 1)
{
the reference is bound to the lvalue result of the conversion
in the second case. */
- z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags);
+ z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags,
+ complain);
if (cand)
return cand->second_conv;
}
if (!conv)
conv = implicit_conversion (to, from, expr, c_cast_p,
- flags);
+ flags, complain);
if (!conv)
return NULL;
static conversion *
implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
- int flags)
+ int flags, tsubst_flags_t complain)
{
conversion *conv;
|LOOKUP_NO_NARROWING|LOOKUP_PROTECT);
if (TREE_CODE (to) == REFERENCE_TYPE)
- conv = reference_binding (to, from, expr, c_cast_p, flags);
+ conv = reference_binding (to, from, expr, c_cast_p, flags, complain);
else
conv = standard_conversion (to, from, expr, c_cast_p, flags);
if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
{
if (is_std_init_list (to))
- return build_list_conv (to, expr, flags);
+ return build_list_conv (to, expr, flags, complain);
/* As an extension, allow list-initialization of _Complex. */
if (TREE_CODE (to) == COMPLEX_TYPE)
{
- conv = build_complex_conv (to, expr, flags);
+ conv = build_complex_conv (to, expr, flags, complain);
if (conv)
return conv;
}
elt = error_mark_node;
conv = implicit_conversion (to, TREE_TYPE (elt), elt,
- c_cast_p, flags);
+ c_cast_p, flags, complain);
if (conv)
{
conv->check_narrowing = true;
}
}
else if (TREE_CODE (to) == ARRAY_TYPE)
- return build_array_conv (to, expr, flags);
+ return build_array_conv (to, expr, flags, complain);
}
if (expr != NULL_TREE
if (CLASS_TYPE_P (to)
&& BRACE_ENCLOSED_INITIALIZER_P (expr)
&& !CLASSTYPE_NON_AGGREGATE (complete_type (to)))
- return build_aggr_conv (to, expr, flags);
+ return build_aggr_conv (to, expr, flags, complain);
- cand = build_user_type_conversion_1 (to, expr, flags);
+ cand = build_user_type_conversion_1 (to, expr, flags, complain);
if (cand)
conv = cand->second_conv;
add_function_candidate (struct z_candidate **candidates,
tree fn, tree ctype, tree first_arg,
const VEC(tree,gc) *args, tree access_path,
- tree conversion_path, int flags)
+ tree conversion_path, int flags,
+ tsubst_flags_t complain)
{
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
int i, len;
lflags |= LOOKUP_ONLYCONVERTING;
t = implicit_conversion (parmtype, argtype, arg,
- /*c_cast_p=*/false, lflags);
+ /*c_cast_p=*/false, lflags, complain);
to_type = parmtype;
}
else
static struct z_candidate *
add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
tree first_arg, const VEC(tree,gc) *arglist,
- tree access_path, tree conversion_path)
+ tree access_path, tree conversion_path,
+ tsubst_flags_t complain)
{
tree totype = TREE_TYPE (TREE_TYPE (fn));
int i, len, viable, flags;
if (i == 0)
{
t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false,
- flags);
+ flags, complain);
convert_type = totype;
}
else if (parmnode == void_list_node)
else if (parmnode)
{
t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg,
- /*c_cast_p=*/false, flags);
+ /*c_cast_p=*/false, flags, complain);
convert_type = TREE_VALUE (parmnode);
}
else
static void
build_builtin_candidate (struct z_candidate **candidates, tree fnname,
tree type1, tree type2, tree *args, tree *argtypes,
- int flags)
+ int flags, tsubst_flags_t complain)
{
conversion *t;
conversion **convs;
break;
t = implicit_conversion (types[i], argtypes[i], args[i],
- /*c_cast_p=*/false, flags);
+ /*c_cast_p=*/false, flags, complain);
if (! t)
{
viable = 0;
/* We need something for printing the candidate. */
t = build_identity_conv (types[i], NULL_TREE);
- reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i], types[i]);
+ reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i],
+ types[i]);
}
else if (t->bad_p)
{
viable = 0;
- reason = bad_arg_conversion_rejection (NULL_TREE, i, argtypes[i], types[i]);
+ reason = bad_arg_conversion_rejection (NULL_TREE, i, argtypes[i],
+ types[i]);
}
convs[i] = t;
}
convs[2] = convs[1];
convs[1] = convs[0];
t = implicit_conversion (boolean_type_node, argtypes[2], args[2],
- /*c_cast_p=*/false, flags);
+ /*c_cast_p=*/false, flags,
+ complain);
if (t)
convs[0] = t;
else
static void
add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
enum tree_code code2, tree fnname, tree type1,
- tree type2, tree *args, tree *argtypes, int flags)
+ tree type2, tree *args, tree *argtypes, int flags,
+ tsubst_flags_t complain)
{
switch (code)
{
if (cptype != error_mark_node)
{
build_builtin_candidate
- (candidates, fnname, cptype, cptype, args, argtypes, flags);
+ (candidates, fnname, cptype, cptype, args, argtypes,
+ flags, complain);
return;
}
}
build_builtin_candidate
- (candidates, fnname, type1, type1, args, argtypes, flags);
+ (candidates, fnname, type1, type1, args, argtypes, flags, complain);
build_builtin_candidate
- (candidates, fnname, type2, type2, args, argtypes, flags);
+ (candidates, fnname, type2, type2, args, argtypes, flags, complain);
return;
}
build_builtin_candidate
- (candidates, fnname, type1, type2, args, argtypes, flags);
+ (candidates, fnname, type1, type2, args, argtypes, flags, complain);
}
tree
static void
add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
enum tree_code code2, tree fnname, tree *args,
- int flags)
+ int flags, tsubst_flags_t complain)
{
int ref1, i;
int enum_p = 0;
case TRUTH_NOT_EXPR:
build_builtin_candidate
(candidates, fnname, boolean_type_node,
- NULL_TREE, args, argtypes, flags);
+ NULL_TREE, args, argtypes, flags, complain);
return;
case TRUTH_ORIF_EXPR:
case TRUTH_ANDIF_EXPR:
build_builtin_candidate
(candidates, fnname, boolean_type_node,
- boolean_type_node, args, argtypes, flags);
+ boolean_type_node, args, argtypes, flags, complain);
return;
case ADDR_EXPR:
FOR_EACH_VEC_ELT_REVERSE (tree, types[1], jx, u)
add_builtin_candidate
(candidates, code, code2, fnname, t,
- u, args, argtypes, flags);
+ u, args, argtypes, flags, complain);
else
add_builtin_candidate
(candidates, code, code2, fnname, t,
- NULL_TREE, args, argtypes, flags);
+ NULL_TREE, args, argtypes, flags, complain);
}
release_tree_vector (types[0]);
tree ctype, tree explicit_targs, tree first_arg,
const VEC(tree,gc) *arglist, tree return_type,
tree access_path, tree conversion_path,
- int flags, tree obj, unification_kind_t strict)
+ int flags, tree obj, unification_kind_t strict,
+ tsubst_flags_t complain)
{
int ntparms = DECL_NTPARMS (tmpl);
tree targs = make_tree_vec (ntparms);
if (obj != NULL_TREE)
/* Aha, this is a conversion function. */
cand = add_conv_candidate (candidates, fn, obj, first_arg, arglist,
- access_path, conversion_path);
+ access_path, conversion_path, complain);
else
cand = add_function_candidate (candidates, fn, ctype,
first_arg, arglist, access_path,
- conversion_path, flags);
+ conversion_path, flags, complain);
if (DECL_TI_TEMPLATE (fn) != tmpl)
/* This situation can occur if a member template of a template
class is specialized. Then, instantiate_template might return
tree explicit_targs, tree first_arg,
const VEC(tree,gc) *arglist, tree return_type,
tree access_path, tree conversion_path, int flags,
- unification_kind_t strict)
+ unification_kind_t strict, tsubst_flags_t complain)
{
return
add_template_candidate_real (candidates, tmpl, ctype,
explicit_targs, first_arg, arglist,
return_type, access_path, conversion_path,
- flags, NULL_TREE, strict);
+ flags, NULL_TREE, strict, complain);
}
tree obj, tree first_arg,
const VEC(tree,gc) *arglist,
tree return_type, tree access_path,
- tree conversion_path)
+ tree conversion_path, tsubst_flags_t complain)
{
return
add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
first_arg, arglist, return_type, access_path,
- conversion_path, 0, obj, DEDUCE_CONV);
+ conversion_path, 0, obj, DEDUCE_CONV,
+ complain);
}
/* The CANDS are the set of candidates that were considered for
tree explicit_targs, bool template_only,
tree conversion_path, tree access_path,
int flags,
- struct z_candidate **candidates)
+ struct z_candidate **candidates,
+ tsubst_flags_t complain)
{
VEC(tree,gc) *args;
args = make_tree_vector_single (init_list);
add_candidates (fns, first_arg, args, NULL_TREE,
explicit_targs, template_only, conversion_path,
- access_path, flags, candidates);
+ access_path, flags, candidates, complain);
if (any_strictly_viable (*candidates))
return;
}
add_candidates (fns, first_arg, args, NULL_TREE,
explicit_targs, template_only, conversion_path,
- access_path, flags, candidates);
+ access_path, flags, candidates, complain);
}
/* Returns the best overload candidate to perform the requested
per [dcl.init.ref], so we ignore temporary bindings. */
static struct z_candidate *
-build_user_type_conversion_1 (tree totype, tree expr, int flags)
+build_user_type_conversion_1 (tree totype, tree expr, int flags,
+ tsubst_flags_t complain)
{
struct z_candidate *candidates, *cand;
tree fromtype;
/* List-initialization. */
add_list_candidates (ctors, first_arg, expr, totype, NULL_TREE,
false, TYPE_BINFO (totype), TYPE_BINFO (totype),
- ctorflags, &candidates);
+ ctorflags, &candidates, complain);
}
else
{
args = make_tree_vector_single (expr);
add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false,
TYPE_BINFO (totype), TYPE_BINFO (totype),
- ctorflags, &candidates);
+ ctorflags, &candidates, complain);
}
for (cand = candidates; cand; cand = cand->next)
add_candidates (TREE_VALUE (conv_fns), first_arg, NULL, totype,
NULL_TREE, false,
conversion_path, TYPE_BINFO (fromtype),
- flags, &candidates);
+ flags, &candidates, complain);
for (cand = candidates; cand != old_candidates; cand = cand->next)
{
= implicit_conversion (totype,
rettype,
0,
- /*c_cast_p=*/false, convflags);
+ /*c_cast_p=*/false, convflags,
+ complain);
/* If LOOKUP_NO_TEMP_BIND isn't set, then this is
copy-initialization. In that case, "The result of the
return NULL;
}
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
- if (flags & LOOKUP_COMPLAIN)
+ if ((flags & LOOKUP_COMPLAIN)
+ && (complain & tf_error))
{
error ("conversion from %qT to %qT is ambiguous",
- fromtype, totype);
+ fromtype, totype);
print_z_candidates (location_of (expr), candidates);
}
/* Wrapper for above. */
tree
-build_user_type_conversion (tree totype, tree expr, int flags)
+build_user_type_conversion (tree totype, tree expr, int flags,
+ tsubst_flags_t complain)
{
struct z_candidate *cand;
tree ret;
bool subtime = timevar_cond_start (TV_OVERLOAD);
- cand = build_user_type_conversion_1 (totype, expr, flags);
+ cand = build_user_type_conversion_1 (totype, expr, flags, complain);
if (cand)
{
ret = error_mark_node;
else
{
- expr = convert_like (cand->second_conv, expr, tf_warning_or_error);
+ expr = convert_like (cand->second_conv, expr, complain);
ret = convert_from_reference (expr);
}
}
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
/*c_cast_p=*/false,
- LOOKUP_IMPLICIT);
+ LOOKUP_IMPLICIT, complain);
/* for a non-type template-parameter of integral or
enumeration type, integral promotions (4.5) and integral
perform_overload_resolution (tree fn,
const VEC(tree,gc) *args,
struct z_candidate **candidates,
- bool *any_viable_p)
+ bool *any_viable_p, tsubst_flags_t complain)
{
struct z_candidate *cand;
tree explicit_targs;
/*conversion_path=*/NULL_TREE,
/*access_path=*/NULL_TREE,
LOOKUP_NORMAL,
- candidates);
+ candidates, complain);
*candidates = splice_viable (*candidates, pedantic, any_viable_p);
if (*any_viable_p)
- cand = tourney (*candidates);
+ cand = tourney (*candidates, complain);
else
cand = NULL;
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
- cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p);
+ cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p,
+ complain);
if (!cand)
{
tree
build_operator_new_call (tree fnname, VEC(tree,gc) **args,
tree *size, tree *cookie_size,
- tree *fn)
+ tree *fn, tsubst_flags_t complain)
{
tree fns;
struct z_candidate *candidates;
if (fn)
*fn = NULL_TREE;
VEC_safe_insert (tree, gc, *args, 0, *size);
- *args = resolve_args (*args, tf_warning_or_error);
+ *args = resolve_args (*args, complain);
if (*args == NULL)
return error_mark_node;
fns = lookup_function_nonclass (fnname, *args, /*block_p=*/false);
/* Figure out what function is being called. */
- cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p);
+ cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p,
+ complain);
/* If no suitable function could be found, issue an error message
and give up. */
if (!cand)
{
- print_error_for_call_failure (fns, *args, any_viable_p, candidates);
+ if (complain & tf_error)
+ print_error_for_call_failure (fns, *args, any_viable_p, candidates);
return error_mark_node;
}
*fn = cand->fn;
/* Build the CALL_EXPR. */
- return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error);
+ return build_over_call (cand, LOOKUP_NORMAL, complain);
}
/* Build a new call to operator(). This may change ARGS. */
first_mem_arg, *args, NULL_TREE,
NULL_TREE, false,
BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns),
- LOOKUP_NORMAL, &candidates);
+ LOOKUP_NORMAL, &candidates, complain);
}
convs = lookup_conversions (type);
add_template_conv_candidate
(&candidates, fn, obj, NULL_TREE, *args, totype,
/*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE);
+ /*conversion_path=*/NULL_TREE, complain);
else
add_conv_candidate (&candidates, fn, obj, NULL_TREE,
*args, /*conversion_path=*/NULL_TREE,
- /*access_path=*/NULL_TREE);
+ /*access_path=*/NULL_TREE, complain);
}
}
}
else
{
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
if (complain & tf_error)
convert E1 to E2 in [expr.cond]. */
static conversion *
-conditional_conversion (tree e1, tree e2)
+conditional_conversion (tree e1, tree e2, tsubst_flags_t complain)
{
tree t1 = non_reference (TREE_TYPE (e1));
tree t2 = non_reference (TREE_TYPE (e2));
e1,
/*c_cast_p=*/false,
LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND
- |LOOKUP_ONLYCONVERTING);
+ |LOOKUP_ONLYCONVERTING,
+ complain);
if (conv)
return conv;
}
converted to the type that expression E2 would have if E2 were
converted to an rvalue (or the type it has, if E2 is an rvalue). */
return implicit_conversion (t2, t1, e1, /*c_cast_p=*/false,
- LOOKUP_IMPLICIT);
+ LOOKUP_IMPLICIT, complain);
}
/* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
- conv2 = conditional_conversion (arg2, arg3);
- conv3 = conditional_conversion (arg3, arg2);
+ conv2 = conditional_conversion (arg2, arg3, complain);
+ conv3 = conditional_conversion (arg3, arg2, complain);
/* [expr.cond]
NOP_EXPR,
ansi_opname (COND_EXPR),
args,
- LOOKUP_NORMAL);
+ LOOKUP_NORMAL, complain);
/* [expr.cond]
}
return error_mark_node;
}
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (!cand)
{
if (complain & tf_error)
tree explicit_targs, bool template_only,
tree conversion_path, tree access_path,
int flags,
- struct z_candidate **candidates)
+ struct z_candidate **candidates,
+ tsubst_flags_t complain)
{
tree ctype;
const VEC(tree,gc) *non_static_args;
access_path,
conversion_path,
flags,
- strict);
+ strict,
+ complain);
else if (!template_only)
add_function_candidate (candidates,
fn,
fn_args,
access_path,
conversion_path,
- flags);
+ flags,
+ complain);
}
}
add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true),
NULL_TREE, arglist, NULL_TREE,
NULL_TREE, false, NULL_TREE, NULL_TREE,
- flags, &candidates);
+ flags, &candidates, complain);
/* Add class-member operators to the candidate set. */
if (CLASS_TYPE_P (TREE_TYPE (arg1)))
{
NULL_TREE, false,
BASELINK_BINFO (fns),
BASELINK_ACCESS_BINFO (fns),
- flags, &candidates);
+ flags, &candidates, complain);
}
args[0] = arg1;
args[1] = arg2;
args[2] = NULL_TREE;
- add_builtin_candidates (&candidates, code, code2, fnname, args, flags);
+ add_builtin_candidates (&candidates, code, code2, fnname, args,
+ flags, complain);
switch (code)
{
}
else
{
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
{
struct candidate_warning *w;
for (w = cand->warnings; w; w = w->next)
- joust (cand, w->loser, 1);
+ joust (cand, w->loser, 1, complain);
}
/* Check for comparison of different enum types. */
if (complain & tf_error)
{
/* Call build_user_type_conversion again for the error. */
- build_user_type_conversion (totype, convs->u.expr, LOOKUP_NORMAL);
+ build_user_type_conversion (totype, convs->u.expr, LOOKUP_NORMAL,
+ complain);
if (fn)
error (" initializing argument %P of %q+D", argnum, fn);
}
required. Return the converted value. */
tree
-convert_arg_to_ellipsis (tree arg)
+convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
{
tree arg_type;
The lvalue-to-rvalue, array-to-pointer, and function-to-pointer
standard conversions are performed. */
- arg = decay_conversion (arg, tf_warning_or_error);
+ arg = decay_conversion (arg, complain);
arg_type = TREE_TYPE (arg);
/* [expr.call]
< TYPE_PRECISION (double_type_node))
&& !DECIMAL_FLOAT_MODE_P (TYPE_MODE (arg_type)))
{
- if (warn_double_promotion && !c_inhibit_evaluation_warnings)
+ if ((complain & tf_warning)
+ && warn_double_promotion && !c_inhibit_evaluation_warnings)
warning (OPT_Wdouble_promotion,
"implicit conversion from %qT to %qT when passing "
"argument to function",
{
if (SCOPED_ENUM_P (arg_type) && !abi_version_at_least (6))
{
- warning (OPT_Wabi, "scoped enum %qT will not promote to an "
- "integral type in a future version of GCC", arg_type);
+ if (complain & tf_warning)
+ warning (OPT_Wabi, "scoped enum %qT will not promote to an "
+ "integral type in a future version of GCC", arg_type);
arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg);
}
arg = perform_integral_promotions (arg);
/* Build up a real lvalue-to-rvalue conversion in case the
copy constructor is trivial but not callable. */
if (!cp_unevaluated_operand && CLASS_TYPE_P (arg_type))
- force_rvalue (arg, tf_warning_or_error);
+ force_rvalue (arg, complain);
/* [expr.call] 5.2.2/7:
Passing a potentially-evaluated argument of class type (Clause 9)
if (cp_unevaluated_operand == 0
&& (type_has_nontrivial_copy_init (arg_type)
|| TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type)))
- error ("cannot pass objects of non-trivially-copyable "
- "type %q#T through %<...%>", arg_type);
+ {
+ if (complain & tf_error)
+ error ("cannot pass objects of non-trivially-copyable "
+ "type %q#T through %<...%>", arg_type);
+ else
+ return error_mark_node;
+ }
}
return arg;
{ VEC_pop (tree, default_arg_context); }
tree
-convert_default_arg (tree type, tree arg, tree fn, int parmnum)
+convert_default_arg (tree type, tree arg, tree fn, int parmnum,
+ tsubst_flags_t complain)
{
int i;
tree t;
FOR_EACH_VEC_ELT (tree, default_arg_context, i, t)
if (t == fn)
{
- error ("recursive evaluation of default argument for %q#D", fn);
+ if (complain & tf_error)
+ error ("recursive evaluation of default argument for %q#D", fn);
return error_mark_node;
}
conversion cannot be performed. */
if (TREE_CODE (arg) == DEFAULT_ARG)
{
- error ("call to %qD uses the default argument for parameter %P, which "
- "is not yet defined", fn, parmnum);
+ if (complain & tf_error)
+ error ("call to %qD uses the default argument for parameter %P, which "
+ "is not yet defined", fn, parmnum);
return error_mark_node;
}
arg = break_out_target_exprs (arg);
if (TREE_CODE (arg) == CONSTRUCTOR)
{
- arg = digest_init (type, arg, tf_warning_or_error);
+ arg = digest_init (type, arg, complain);
arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
ICR_DEFAULT_ARGUMENT, fn, parmnum,
- tf_warning_or_error);
+ complain);
}
else
{
arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
ICR_DEFAULT_ARGUMENT, fn, parmnum,
- tf_warning_or_error);
- arg = convert_for_arg_passing (type, arg);
+ complain);
+ arg = convert_for_arg_passing (type, arg, complain);
}
pop_deferring_access_checks();
/* Actually perform the appropriate conversion. */
tree
-convert_for_arg_passing (tree type, tree val)
+convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
{
tree bitfield_type;
&& INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
TYPE_SIZE (integer_type_node)))
val = perform_integral_promotions (val);
- if (warn_missing_format_attribute)
+ if ((complain & tf_warning)
+ && warn_missing_format_attribute)
{
tree rhstype = TREE_TYPE (val);
const enum tree_code coder = TREE_CODE (rhstype);
{
struct candidate_warning *w;
for (w = cand->warnings; w; w = w->next)
- joust (cand, w->loser, 1);
+ joust (cand, w->loser, 1, complain);
}
/* Make =delete work with SFINAE. */
? complain
: complain & (~tf_warning));
- val = convert_for_arg_passing (type, val);
+ val = convert_for_arg_passing (type, val, complain);
if (val == error_mark_node)
return error_mark_node;
else
return error_mark_node;
argarray[j++] = convert_default_arg (TREE_VALUE (parm),
TREE_PURPOSE (parm),
- fn, i - is_method);
+ fn, i - is_method,
+ complain);
}
/* Ellipsis */
/* Do no conversions for magic varargs. */
a = mark_type_use (a);
else
- a = convert_arg_to_ellipsis (a);
+ a = convert_arg_to_ellipsis (a, complain);
argarray[j++] = a;
}
/* Otherwise go ahead with overload resolution. */
add_list_candidates (fns, first_mem_arg, init_list,
basetype, explicit_targs, template_only,
- conversion_path, access_binfo, flags, &candidates);
+ conversion_path, access_binfo, flags,
+ &candidates, complain);
}
else
{
add_candidates (fns, first_mem_arg, user_args, optype,
explicit_targs, template_only, conversion_path,
- access_binfo, flags, &candidates);
+ access_binfo, flags, &candidates, complain);
}
any_viable_p = false;
candidates = splice_viable (candidates, pedantic, &any_viable_p);
}
else
{
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
char *pretty_name;
0: cand1 and cand2 are indistinguishable */
static int
-joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
+joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
+ tsubst_flags_t complain)
{
int winner = 0;
int off1 = 0, off2 = 0;
if (comp != 0)
{
- if (warn_sign_promo
+ if ((complain & tf_warning)
+ && warn_sign_promo
&& (CONVERSION_RANK (t1) + CONVERSION_RANK (t2)
== cr_std + cr_promotion)
&& t1->kind == ck_std
/* warn about confusing overload resolution for user-defined conversions,
either between a constructor and a conversion op, or between two
conversion ops. */
- if (winner && warn_conversion && cand1->second_conv
+ if ((complain & tf_warning)
+ && winner && warn_conversion && cand1->second_conv
&& (!DECL_CONSTRUCTOR_P (cand1->fn) || !DECL_CONSTRUCTOR_P (cand2->fn))
&& winner != compare_ics (cand1->second_conv, cand2->second_conv))
{
{
if (warn)
{
- permerror (input_location, "default argument mismatch in "
- "overload resolution");
- inform (input_location,
- " candidate 1: %q+#F", cand1->fn);
- inform (input_location,
- " candidate 2: %q+#F", cand2->fn);
+ if (complain & tf_error)
+ {
+ permerror (input_location,
+ "default argument mismatch in "
+ "overload resolution");
+ inform (input_location,
+ " candidate 1: %q+#F", cand1->fn);
+ inform (input_location,
+ " candidate 2: %q+#F", cand2->fn);
+ }
+ else
+ return 0;
}
else
add_warning (cand1, cand2);
/* Extension: If the worst conversion for one candidate is worse than the
worst conversion for the other, take the first. */
- if (!pedantic)
+ if (!pedantic && (complain & tf_warning_or_error))
{
conversion_rank rank1 = cr_identity, rank2 = cr_identity;
struct z_candidate *w = 0, *l = 0;
algorithm. */
static struct z_candidate *
-tourney (struct z_candidate *candidates)
+tourney (struct z_candidate *candidates, tsubst_flags_t complain)
{
struct z_candidate *champ = candidates, *challenger;
int fate;
for (challenger = champ->next; challenger; )
{
- fate = joust (champ, challenger, 0);
+ fate = joust (champ, challenger, 0, complain);
if (fate == 1)
challenger = challenger->next;
else
&& !(champ_compared_to_predecessor && challenger->next == champ);
challenger = challenger->next)
{
- fate = joust (champ, challenger, 0);
+ fate = joust (champ, challenger, 0, complain);
if (fate != 1)
return NULL;
}
/* Returns nonzero if things of type FROM can be converted to TO. */
bool
-can_convert (tree to, tree from)
+can_convert (tree to, tree from, tsubst_flags_t complain)
{
- return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT);
+ return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT, complain);
}
/* Returns nonzero if ARG (of type FROM) can be converted to TO. */
bool
-can_convert_arg (tree to, tree from, tree arg, int flags)
+can_convert_arg (tree to, tree from, tree arg, int flags,
+ tsubst_flags_t complain)
{
conversion *t;
void *p;
p = conversion_obstack_alloc (0);
t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
- flags);
+ flags, complain);
ok_p = (t && !t->bad_p);
/* Free all the conversions we allocated. */
/* Like can_convert_arg, but allows dubious conversions as well. */
bool
-can_convert_arg_bad (tree to, tree from, tree arg, int flags)
+can_convert_arg_bad (tree to, tree from, tree arg, int flags,
+ tsubst_flags_t complain)
{
conversion *t;
void *p;
p = conversion_obstack_alloc (0);
/* Try to perform the conversion. */
t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
- flags);
+ flags, complain);
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
doing a bad conversion, convert_like will complain. */
tree
-perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain, int flags)
+perform_implicit_conversion_flags (tree type, tree expr,
+ tsubst_flags_t complain, int flags)
{
conversion *conv;
void *p;
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
/*c_cast_p=*/false,
- flags);
+ flags, complain);
if (!conv)
{
tree
perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
{
- return perform_implicit_conversion_flags (type, expr, complain, LOOKUP_IMPLICIT);
+ return perform_implicit_conversion_flags (type, expr, complain,
+ LOOKUP_IMPLICIT);
}
/* Convert EXPR to TYPE (as a direct-initialization) if that is
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
c_cast_p,
- LOOKUP_NORMAL);
+ LOOKUP_NORMAL, complain);
if (!conv || conv->bad_p)
expr = NULL_TREE;
else
p = conversion_obstack_alloc (0);
conv = reference_binding (type, TREE_TYPE (expr), expr, /*c_cast_p=*/false,
- flags);
+ flags, complain);
if (!conv || conv->bad_p)
{
if (complain & tf_error)