typeck.c (build_c_cast): Don't decay arrays and functions to pointer type when converting to a class type.
* typeck.c (build_c_cast): Don't decay arrays and functions to pointer type when converting to a class type. From-SVN: r19659
This commit is contained in:
parent
e1b1668d45
commit
4785faf117
|
@ -1,3 +1,8 @@
|
|||
Sun May 10 23:43:13 1998 Mark Mitchell <mmitchell@usa.net>
|
||||
|
||||
* typeck.c (build_c_cast): Don't decay arrays and functions to
|
||||
pointer type when converting to a class type.
|
||||
|
||||
Sun May 10 22:53:56 1998 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* cp-tree.h (DECL_NAMESPACE_SCOPE): New macro.
|
||||
|
|
|
@ -5633,16 +5633,36 @@ build_c_cast (type, expr)
|
|||
|
||||
/* Convert functions and arrays to pointers and
|
||||
convert references to their expanded types,
|
||||
but don't convert any other types. */
|
||||
if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
|
||||
|| (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE
|
||||
/* Don't do the default conversion if we want a
|
||||
pointer to a function. */
|
||||
&& ! (TREE_CODE (type) == POINTER_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
|
||||
|| TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
|
||||
value = default_conversion (value);
|
||||
but don't convert any other types. If, however, we are
|
||||
casting to a class type, there's no reason to do this: the
|
||||
cast will only succeed if there is a converting constructor,
|
||||
and the default conversions will be done at that point. In
|
||||
fact, doing the default conversion here is actually harmful
|
||||
in cases like this:
|
||||
|
||||
typedef int A[2];
|
||||
struct S { S(const A&); };
|
||||
|
||||
since we don't want the array-to-pointer conversion done. */
|
||||
if (!IS_AGGR_TYPE (type))
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
|
||||
|| (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE
|
||||
/* Don't do the default conversion if we want a
|
||||
pointer to a function. */
|
||||
&& ! (TREE_CODE (type) == POINTER_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
|
||||
|| TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
|
||||
value = default_conversion (value);
|
||||
}
|
||||
else if (TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
|
||||
/* However, even for class types, we still need to strip away
|
||||
the reference type, since the call to convert_force below
|
||||
does not expect the input expression to be of reference
|
||||
type. */
|
||||
value = convert_from_reference (value);
|
||||
|
||||
otype = TREE_TYPE (value);
|
||||
|
||||
/* Optionally warn about potentially worrisome casts. */
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// Build don't link:
|
||||
|
||||
typedef int Array_T[2];
|
||||
|
||||
struct S1 {
|
||||
S1(const Array_T&);
|
||||
};
|
||||
|
||||
struct S2 {
|
||||
S1 g();
|
||||
Array_T a;
|
||||
};
|
||||
|
||||
S1 S2::g()
|
||||
{
|
||||
return S1(a);
|
||||
}
|
||||
|
||||
void h()
|
||||
{
|
||||
S2 s2;
|
||||
s2.g();
|
||||
}
|
Loading…
Reference in New Issue