/* OK */;
else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from)))
conv = build_conv (QUAL_CONV, to, conv);
+ else if (expr && string_conv_p (to, expr, 0))
+ /* converting from string constant to char *. */
+ conv = build_conv (QUAL_CONV, to, conv);
else if (ptr_reasonably_similar (TREE_TYPE (to), TREE_TYPE (from)))
{
conv = build_conv (PTR_CONV, to, conv);
case LVALUE_CONV:
return decay_conversion (expr);
+ case QUAL_CONV:
+ /* Warn about deprecated conversion if appropriate. */
+ string_conv_p (TREE_TYPE (convs), expr, 1);
+ break;
+
default:
break;
}
{
tree parmtype = TREE_VALUE (parm);
tree argtype = TREE_TYPE (TREE_VALUE (arg));
+ tree t;
if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i)))
{
int dv = (TYPE_VOLATILE (TREE_TYPE (parmtype))
cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards %s",
TREE_TYPE (argtype), fn, p);
}
- converted_args = expr_tree_cons
- (NULL_TREE, convert_force (TREE_VALUE (parm), TREE_VALUE (arg), CONV_C_CAST),
- converted_args);
+ /* [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
+ derived from X, the behavior is undefined.
+
+ So we can assume that anything passed as 'this' is non-null, and
+ optimize accordingly. */
+ if (TREE_CODE (parmtype) == POINTER_TYPE)
+ t = convert_pointer_to_real (TREE_TYPE (parmtype), TREE_VALUE (arg));
+ else
+ /* This happens with signatures. */
+ t = convert_force (parmtype, TREE_VALUE (arg), CONV_C_CAST);
+ converted_args = expr_tree_cons (NULL_TREE, t, converted_args);
parm = TREE_CHAIN (parm);
arg = TREE_CHAIN (arg);
++i;
/* Avoid actually calling copy constructors and copy assignment operators,
if possible. */
- if (DECL_CONSTRUCTOR_P (fn)
- && TREE_VEC_LENGTH (convs) == 1
+
+ if (! flag_elide_constructors)
+ /* Do things the hard way. */;
+ else if (DECL_CONSTRUCTOR_P (fn)
+ && TREE_VEC_LENGTH (convs) == 1
&& copy_args_p (fn))
{
tree targ;