diff options
author | Mark Mitchell <mmitchell@usa.net> | 1998-05-10 23:46:36 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-05-10 23:46:36 +0000 |
commit | 4785faf11744c7e86ac93032075b23becebef200 (patch) | |
tree | 8af3e025a91323607b63011f8ad4ad4dbfef73b9 | |
parent | e1b1668d45ab0993390510ac0c042746eefa0f8f (diff) | |
download | gcc-4785faf11744c7e86ac93032075b23becebef200.zip gcc-4785faf11744c7e86ac93032075b23becebef200.tar.gz gcc-4785faf11744c7e86ac93032075b23becebef200.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/cvt1.C | 23 |
3 files changed, 58 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 95eb36e..315feea 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 6c1a1a6..fe66a3b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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. */ diff --git a/gcc/testsuite/g++.old-deja/g++.other/cvt1.C b/gcc/testsuite/g++.old-deja/g++.other/cvt1.C new file mode 100644 index 0000000..f448cc1a --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/cvt1.C @@ -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(); +} |