aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2002-11-07 21:33:44 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2002-11-07 21:33:44 +0000
commitf72ab53b264bdd34a0a0985d609b1b27f16fdb9b (patch)
tree0736c00c81f57f19c12f944af5c35fda1007c5c3
parent0977774ba0e8c40e13183a40300a255a803ecf89 (diff)
downloadgcc-f72ab53b264bdd34a0a0985d609b1b27f16fdb9b.zip
gcc-f72ab53b264bdd34a0a0985d609b1b27f16fdb9b.tar.gz
gcc-f72ab53b264bdd34a0a0985d609b1b27f16fdb9b.tar.bz2
class.c (add_implicitly_declared_members): Put implicitly declared functions at the end of TYPE_METHODs when...
* class.c (add_implicitly_declared_members): Put implicitly declared functions at the end of TYPE_METHODs when -fabi-version is at least 2. * testsuite/g++.dg/abi/dtor1.C: New test. * testsuite/g++.dg/abi/dtor2.C: Likewise. From-SVN: r58908
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/class.c23
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/abi/dtor1.C22
-rw-r--r--gcc/testsuite/g++.dg/abi/dtor2.C14
5 files changed, 64 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d542e25..3f37368 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_implicitly_declared_members): Put implicitly
+ declared functions at the end of TYPE_METHODs when -fabi-version
+ is at least 2.
+
2002-11-05 Geoffrey Keating <geoffk@apple.com>
* decl2.c (finish_file): Correct spelling.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0dffc62..82f7c8f 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -125,7 +125,7 @@ static void finish_struct_methods PARAMS ((tree));
static void maybe_warn_about_overly_private_class PARAMS ((tree));
static int field_decl_cmp PARAMS ((const tree *, const tree *));
static int method_name_cmp PARAMS ((const tree *, const tree *));
-static tree add_implicitly_declared_members PARAMS ((tree, int, int, int));
+static void add_implicitly_declared_members PARAMS ((tree, int, int, int));
static tree fixed_type_or_null PARAMS ((tree, int *, int *));
static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int,
int, int, tree));
@@ -2742,7 +2742,7 @@ maybe_add_class_template_decl_list (type, t, friend_p)
reference, respectively. If a virtual destructor is created, its
DECL is returned; otherwise the return value is NULL_TREE. */
-static tree
+static void
add_implicitly_declared_members (t, cant_have_default_ctor,
cant_have_const_cctor,
cant_have_const_assignment)
@@ -2817,12 +2817,23 @@ add_implicitly_declared_members (t, cant_have_default_ctor,
add_method (t, *f, /*error_p=*/0);
maybe_add_class_template_decl_list (current_class_type, *f, /*friend_p=*/0);
}
- *f = TYPE_METHODS (t);
- TYPE_METHODS (t) = implicit_fns;
+ if (abi_version_at_least (2))
+ /* G++ 3.2 put the implicit destructor at the *beginning* of the
+ list, which cause the destructor to be emitted in an incorrect
+ location in the vtable. */
+ TYPE_METHODS (t) = chainon (TYPE_METHODS (t), implicit_fns);
+ else
+ {
+ if (warn_abi && virtual_dtor)
+ warning ("vtable layout for class `%T' may not be ABI-compliant "
+ "and may change in a future version of GCC due to implicit "
+ "virtual destructor",
+ t);
+ *f = TYPE_METHODS (t);
+ TYPE_METHODS (t) = implicit_fns;
+ }
--adding_implicit_members;
-
- return virtual_dtor;
}
/* Subroutine of finish_struct_1. Recursively count the number of fields
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 38c0f8b..7ad265e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
+ * testsuite/g++.dg/abi/dtor1.C: New test.
+ * testsuite/g++.dg/abi/dtor2.C: Likewise.
+
2002-11-05 Geoffrey Keating <geoffk@apple.com>
* g++.old-deja/g++.eh/badalloc1.C: XFAIL excess errors test on
diff --git a/gcc/testsuite/g++.dg/abi/dtor1.C b/gcc/testsuite/g++.dg/abi/dtor1.C
new file mode 100644
index 0000000..48b0a55
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/dtor1.C
@@ -0,0 +1,22 @@
+// { dg-do compile { target i?86-*-* } }
+// { dg-options "-fabi-version=0" }
+
+struct A {
+ virtual void a ();
+};
+
+struct B {
+ virtual ~B ();
+};
+
+struct C : public A, public B {
+ virtual void c ();
+};
+
+struct D : virtual public C {
+ virtual void d ();
+};
+
+void D::d () {}
+
+// { dg-final { scan-assembler _ZTv0_n20_N1DD1Ev } }
diff --git a/gcc/testsuite/g++.dg/abi/dtor2.C b/gcc/testsuite/g++.dg/abi/dtor2.C
new file mode 100644
index 0000000..f4a1336
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/dtor2.C
@@ -0,0 +1,14 @@
+// { dg-do compile }
+// { dg-options "-Wabi" }
+
+struct A {
+ virtual void a ();
+};
+
+struct B {
+ virtual ~B ();
+};
+
+struct C : public A, public B { // { dg-warning "virtual" }
+ virtual void c ();
+};