(struct z_candidate **, tree, tree, tree, tree, tree);
static struct z_candidate *add_function_candidate
(struct z_candidate **, tree, tree, tree, tree, tree, int);
-static conversion *implicit_conversion (tree, tree, tree, int);
-static conversion *standard_conversion (tree, tree, tree, int);
+static conversion *implicit_conversion (tree, tree, tree, bool, int);
+static conversion *standard_conversion (tree, tree, tree, bool, int);
static conversion *reference_binding (tree, tree, tree, int);
static conversion *build_conv (conversion_kind, tree, conversion *);
static bool is_subseq (conversion *, conversion *);
/* Returns the standard conversion path (see [conv]) from type FROM to type
TO, if any. For proper handling of null pointer constants, you must
- also pass the expression EXPR to convert from. */
+ also pass the expression EXPR to convert from. If C_CAST_P is true,
+ this conversion is coming from a C-style cast. */
static conversion *
-standard_conversion (tree to, tree from, tree expr, int flags)
+standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
+ int flags)
{
enum tree_code fcode, tcode;
conversion *conv;
the standard conversion sequence to perform componentwise
conversion. */
conversion *part_conv = standard_conversion
- (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, flags);
+ (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags);
if (part_conv)
{
if (same_type_p (from, to))
/* OK */;
- else if (comp_ptr_ttypes (to_pointee, from_pointee))
+ else if (c_cast_p && comp_ptr_ttypes_const (to, from))
+ /* In a C-style cast, we ignore CV-qualification because we
+ are allowed to perform a static_cast followed by a
+ const_cast. */
+ conv = build_conv (ck_qual, to, conv);
+ else if (!c_cast_p && comp_ptr_ttypes (to_pointee, from_pointee))
conv = build_conv (ck_qual, to, conv);
else if (expr && string_conv_p (to, expr, 0))
/* converting from string constant to char *. */
if (related_p && !at_least_as_qualified_p (to, from))
return NULL;
- conv = implicit_conversion (to, from, expr, flags);
+ conv = implicit_conversion (to, from, expr, /*c_cast_p=*/false,
+ flags);
if (!conv)
return NULL;
return conv;
}
-/* Returns the implicit conversion sequence (see [over.ics]) from type FROM
- to type TO. The optional expression EXPR may affect the conversion.
- FLAGS are the usual overloading flags. Only LOOKUP_NO_CONVERSION is
- significant. */
+/* Returns the implicit conversion sequence (see [over.ics]) from type
+ FROM to type TO. The optional expression EXPR may affect the
+ conversion. FLAGS are the usual overloading flags. Only
+ LOOKUP_NO_CONVERSION is significant. If C_CAST_P is true, this
+ conversion is coming from a C-style cast. */
static conversion *
-implicit_conversion (tree to, tree from, tree expr, int flags)
+implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
+ int flags)
{
conversion *conv;
if (TREE_CODE (to) == REFERENCE_TYPE)
conv = reference_binding (to, from, expr, flags);
else
- conv = standard_conversion (to, from, expr, flags);
+ conv = standard_conversion (to, from, expr, c_cast_p, flags);
if (conv)
return conv;
parmtype = build_pointer_type (parmtype);
}
- t = implicit_conversion (parmtype, argtype, arg, flags);
+ t = implicit_conversion (parmtype, argtype, arg,
+ /*c_cast_p=*/false, flags);
}
else
{
conversion *t;
if (i == 0)
- t = implicit_conversion (totype, argtype, arg, flags);
+ t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false,
+ flags);
else if (parmnode == void_list_node)
break;
else if (parmnode)
- t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, flags);
+ t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg,
+ /*c_cast_p=*/false, flags);
else
{
t = build_identity_conv (argtype, arg);
if (! args[i])
break;
- t = implicit_conversion (types[i], argtypes[i], args[i], flags);
+ t = implicit_conversion (types[i], argtypes[i], args[i],
+ /*c_cast_p=*/false, flags);
if (! t)
{
viable = 0;
{
convs[2] = convs[1];
convs[1] = convs[0];
- t = implicit_conversion (boolean_type_node, argtypes[2], args[2], flags);
+ t = implicit_conversion (boolean_type_node, argtypes[2], args[2],
+ /*c_cast_p=*/false, flags);
if (t)
convs[0] = t;
else
conversion *ics
= implicit_conversion (totype,
TREE_TYPE (TREE_TYPE (cand->fn)),
- 0, convflags);
+ 0,
+ /*c_cast_p=*/false, convflags);
cand->second_conv = ics;
conv = implicit_conversion (build_reference_type (t2),
t1,
e1,
+ /*c_cast_p=*/false,
LOOKUP_NO_TEMP_BIND);
if (conv)
return conv;
Otherwise: E1 can be converted to match E2 if E1 can be implicitly
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, LOOKUP_NORMAL);
+ return implicit_conversion (t2, t1, e1, /*c_cast_p=*/false,
+ LOOKUP_NORMAL);
}
/* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
- t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
+ t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
+ LOOKUP_NORMAL);
ok_p = (t && !t->bad_p);
/* Free all the conversions we allocated. */
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
/* Try to perform the conversion. */
- t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
+ t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
+ LOOKUP_NORMAL);
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
p = conversion_obstack_alloc (0);
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ /*c_cast_p=*/false,
LOOKUP_NORMAL);
if (!conv)
{
p = conversion_obstack_alloc (0);
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ c_cast_p,
LOOKUP_NORMAL);
if (!conv || conv->bad_p)
expr = NULL_TREE;