aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-03-18 06:24:24 -0500
committerJason Merrill <jason@gcc.gnu.org>2002-03-18 06:24:24 -0500
commitffd696af84c29fe41b43e74fb6e4ada9076102d6 (patch)
treeacc35e62bb34fcb06c3819084139135516383189
parent38cb4e84073fecc93460df13daf98f3ad3f72b98 (diff)
downloadgcc-ffd696af84c29fe41b43e74fb6e4ada9076102d6.zip
gcc-ffd696af84c29fe41b43e74fb6e4ada9076102d6.tar.gz
gcc-ffd696af84c29fe41b43e74fb6e4ada9076102d6.tar.bz2
PR c++/3948 -- C++ ABI change, followup to 2001-12-18 patch.
* class.c (finish_struct_bits): Also set TREE_ADDRESSABLE for a type with a nontrivial destructor. From-SVN: r50959
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/class.c9
-rw-r--r--gcc/testsuite/g++.dg/init/byval1.C31
3 files changed, 42 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d27a93b..8fc4c80 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2002-03-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/3948 -- C++ ABI change, followup to 2001-12-18 patch.
+ * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE for a
+ type with a nontrivial destructor.
+
2002-03-17 Jason Merrill <jason@redhat.com>
PR c++/4460
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 8923916..1c0c526 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1879,15 +1879,16 @@ finish_struct_bits (t)
}
}
- /* If this type has a copy constructor, force its mode to be BLKmode, and
- force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to
- be passed by invisible reference and prevent it from being returned in
- a register.
+ /* If this type has a copy constructor or a destructor, force its mode to
+ be BLKmode, and force its TREE_ADDRESSABLE bit to be nonzero. This
+ will cause it to be passed by invisible reference and prevent it from
+ being returned in a register.
Also do this if the class has BLKmode but can still be returned in
registers, since function_cannot_inline_p won't let us inline
functions returning such a type. This affects the HP-PA. */
if (! TYPE_HAS_TRIVIAL_INIT_REF (t)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
|| (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t)
&& CLASSTYPE_NON_AGGREGATE (t)))
{
diff --git a/gcc/testsuite/g++.dg/init/byval1.C b/gcc/testsuite/g++.dg/init/byval1.C
new file mode 100644
index 0000000..86c6e46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/byval1.C
@@ -0,0 +1,31 @@
+// PR c++/3948
+// Test that the destructor call for a value parameter gets the
+// right address.
+
+// { dg-do run }
+
+void *p[2];
+int i;
+int r;
+
+struct C
+{
+ int m;
+
+ C() { p[i++] = this; }
+ ~C() { if (p[--i] != this) r = 1; }
+};
+
+
+void Foo (C c)
+{
+ p[i++] = &c;
+}
+
+int main ()
+{
+ C c;
+
+ Foo (c);
+ return r;
+}