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:
Mark Mitchell 1998-05-10 23:46:36 +00:00 committed by Mark Mitchell
parent e1b1668d45
commit 4785faf117
3 changed files with 58 additions and 10 deletions

View File

@ -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.

View File

@ -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. */

View File

@ -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();
}