This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Virtual destructor failed call on gcc 2.95.2
- To: "Barry M. Caceres" <barryc at itravelpartners dot com>
- Subject: Re: Virtual destructor failed call on gcc 2.95.2
- From: Alexandre Oliva <oliva at lsd dot ic dot unicamp dot br>
- Date: 19 Nov 1999 04:46:52 -0200
- Cc: gcc-bugs at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- References: <38344D57.90FB2F7E@itravelpartners.com> <orso23fvk7.fsf@garnize.lsd.ic.unicamp.br> <38347128.4C0CD8BA@itravelpartners.com>
On Nov 18, 1999, "Barry M. Caceres" <barryc@itravelpartners.com> wrote:
> deletion of the array via the Bar* typed pointer SHOULD call the
> both the ~Foo() and ~Bar() destructors.
Yup. But your bug report referred about virtual destructors, not
destructors of virtual bases, so I misunderstood the problem.
In fact, gcc appears to *never* destruct virtual bases of elements of
arrays :-(
Unless you apply the following patch. It causes no regressions in the
current CVS tree. Ok to install?
? gcc/testsuite/g++.old-deja/g++.oliva/delete3.s
Index: gcc/testsuite/g++.old-deja/g++.oliva/delete2.C
===================================================================
RCS file: delete2.C
diff -N delete2.C
--- gcc/testsuite/g++.old-deja/g++.oliva/delete2.C Tue May 5 13:32:27 1998
+++ gcc/testsuite/g++.old-deja/g++.oliva/delete2.C Thu Nov 18 22:42:34 1999
@@ -0,0 +1,25 @@
+// Copyright (C) 1999 Free Software Foundation
+
+// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+// distilled from bug report by Barry M. Caceres <barryc@itravelpartners.com>
+
+// Test whether dtors of vbases are called on delete[].
+
+extern "C" void abort();
+extern "C" void exit(int);
+
+struct Foo {
+ ~Foo() {
+ std::exit(0);
+ }
+};
+
+struct Bar : virtual Foo {
+};
+
+int main() {
+ delete [] new Bar[1];
+ std::abort();
+}
+
+
Index: gcc/testsuite/g++.old-deja/g++.oliva/delete3.C
===================================================================
RCS file: delete3.C
diff -N delete3.C
--- gcc/testsuite/g++.old-deja/g++.oliva/delete3.C Tue May 5 13:32:27 1998
+++ gcc/testsuite/g++.old-deja/g++.oliva/delete3.C Thu Nov 18 22:42:34 1999
@@ -0,0 +1,36 @@
+// Copyright (C) 1999 Free Software Foundation
+
+// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+// Test whether dtors of vbases are called on throw within new[].
+// Variant of delete2.C.
+
+extern "C" void abort();
+extern "C" void exit(int);
+
+struct Foo {
+ static bool first;
+
+ Foo() {
+ if (first)
+ first = false;
+ else
+ throw first;
+ }
+
+ ~Foo() {
+ std::exit(0);
+ }
+};
+
+bool Foo::first = true;
+
+struct Bar : virtual Foo {
+};
+
+int main() {
+ delete [] new Bar[2];
+ std::abort();
+}
+
+
Index: gcc/testsuite/g++.old-deja/g++.oliva/delete4.C
===================================================================
RCS file: delete4.C
diff -N delete4.C
--- gcc/testsuite/g++.old-deja/g++.oliva/delete4.C Tue May 5 13:32:27 1998
+++ gcc/testsuite/g++.old-deja/g++.oliva/delete4.C Thu Nov 18 22:42:34 1999
@@ -0,0 +1,29 @@
+// Copyright (C) 1999 Free Software Foundation
+
+// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+// Test whether dtors of vbases are called from dtor of aggregate of array.
+// Variant of delete2.C and delete3.C.
+
+extern "C" void abort();
+extern "C" void exit(int);
+
+struct Foo {
+ ~Foo() {
+ std::exit(0);
+ }
+};
+
+struct Bar : virtual Foo {
+};
+
+struct Baz {
+ Bar i[1];
+};
+
+int main() {
+ Baz();
+ std::abort();
+}
+
+
Index: gcc/testsuite/g++.old-deja/g++.oliva/delete5.C
===================================================================
RCS file: delete5.C
diff -N delete5.C
--- gcc/testsuite/g++.old-deja/g++.oliva/delete5.C Tue May 5 13:32:27 1998
+++ gcc/testsuite/g++.old-deja/g++.oliva/delete5.C Thu Nov 18 22:42:34 1999
@@ -0,0 +1,29 @@
+// Copyright (C) 1999 Free Software Foundation
+
+// by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+// Test whether dtors of vbases are called from dtor of auto array.
+// Variant of delete2.C, delete3.C and delete4.C.
+
+extern "C" void abort();
+extern "C" void exit(int);
+
+struct Foo {
+ ~Foo() {
+ std::exit(0);
+ }
+};
+
+struct Bar : virtual Foo {
+};
+
+void foo() {
+ Bar i[1];
+}
+
+int main() {
+ foo();
+ std::abort();
+}
+
+
Index: gcc/cp/ChangeLog
from Alexandre Oliva <oliva@lsd.ic.unicamp.br>
* decl2.c (delete_sanity): Destruct virtual bases when deleting
array. Fixes g++.oliva/delete2.C.
* init.c (build_vec_init): Destruct virtual bases when new array
throws. Fixes g++.oliva/delete3.C.
(build_delete): Destruct virtual bases of elements of arrays.
Fixes g++.oliva/delete4.C and g++.oliva/delete5.C.
Index: gcc/cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.280
diff -u -r1.280 decl2.c
--- gcc/cp/decl2.c 1999/11/16 01:37:38 1.280
+++ gcc/cp/decl2.c 1999/11/19 06:42:46
@@ -1198,7 +1198,7 @@
if (doing_vec)
return build_vec_delete (t, maxindex, integer_one_node,
- integer_zero_node, use_global_delete);
+ integer_two_node, use_global_delete);
else
{
if (IS_AGGR_TYPE (TREE_TYPE (type))
Index: gcc/cp/init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.151
diff -u -r1.151 init.c
--- gcc/cp/init.c 1999/11/14 20:29:03 1.151
+++ gcc/cp/init.c 1999/11/19 06:42:48
@@ -2909,7 +2909,7 @@
iterator),
type,
/*auto_delete_vec=*/integer_zero_node,
- /*auto_delete=*/integer_zero_node,
+ /*auto_delete=*/integer_two_node,
/*use_global_delete=*/0);
finish_cleanup (e, try_block);
}
@@ -3014,7 +3014,7 @@
return error_mark_node;
}
return build_vec_delete (addr, array_type_nelts (type),
- auto_delete, integer_zero_node,
+ auto_delete, integer_two_node,
use_global_delete);
}
else
--
Alexandre Oliva http://www.ic.unicamp.br/~oliva IC-Unicamp, Bra[sz]il
oliva@{lsd.ic.unicamp.br,guarana.{org,com}} aoliva@{acm,computer}.org
oliva@{gnu.org,kaffe.org,{egcs,sourceware}.cygnus.com,samba.org}
** I may forward mail about projects to mailing lists; please use them