aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mmitchell@usa.net>1998-05-10 23:46:36 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-05-10 23:46:36 +0000
commit4785faf11744c7e86ac93032075b23becebef200 (patch)
tree8af3e025a91323607b63011f8ad4ad4dbfef73b9 /gcc
parente1b1668d45ab0993390510ac0c042746eefa0f8f (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/typeck.c40
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/cvt1.C23
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();
+}